package com.hnu.store.controller;

import com.hnu.store.dto.UserDTO;
import com.hnu.store.entity.User;
import com.hnu.store.service.IUserService;
import com.hnu.store.service.ex.CaptchaException;
import com.hnu.store.service.ex.EmailException;
import com.hnu.store.service.ex.UserNotExistException;
import com.hnu.store.utils.JsonResult;
import com.hnu.store.utils.JwtUtils;
import java.util.HashMap;
import java.util.Objects;
import javax.servlet.http.HttpServletResponse;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.CrossOrigin;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;
import org.springframework.web.multipart.MultipartFile;

/**
 *   控制层依赖于业务层接口
 *   RestController的作用等同于controller＋requestbody
 */
@RestController
//  处理跨域问题
@CrossOrigin
@RequestMapping("user")
public class UserController extends BaseController {

  @Autowired
  private IUserService userService;

  /**
   *   HashMap，key是邮箱，value是验证码
   *   解决并发问题，防止多个用户使用同一个验证码
   */
  private final HashMap<String, String> captchaList = new HashMap<>();

  /**
   * 注册
   * @param user 用户名和密码
   * @param captcha 验证码
   * @return 返回json
   */

  @RequestMapping("register")
  public JsonResult register(User user, String captcha) {
    //  验证码错误
    if (!Objects.equals(captchaList.get(user.getEmail()), captcha)) {
      throw new CaptchaException("验证码错误");
    }
    userService.register(user);
    //  注册过程中产生异常会被基类的异常处理捕获
    return new JsonResult(OK);
  }

  /**
   * 发送验证码
   * @param receiver 接收邮箱
   * @return 返回json
   */
  @RequestMapping("sendCaptcha")
  public JsonResult sendCaptcha(String receiver) {
    String captcha = userService.sendCaptcha(receiver);
    //  hashmap会直接进行覆盖
    captchaList.put(receiver, captcha);

    /*
      验证码发送异常会被捕获，否则返回data为captcha的json数据
      前端调用，读取data作为正确的验证码，与用户输入的验证码进行对比
     */
    return new JsonResult(OK);
  }


  /**
   * 登录
   * @param username 用户名
   * @param password 密码
   * @return 返回token加用户信息
   */
  @RequestMapping("login")
  public JsonResult login(String username, String password) {
    //  返回登录查询到的user对象，如果有错会抛出
    UserDTO data = userService.login(username, password);
    //  没有异常返回一个user的json数据
    String token = JwtUtils.generateToken(username);
    JsonResult result = new JsonResult(OK);
    result.addData("token", token);
    result.addData("userInfo", data);
    return result;
  }

  /**
   * 修改用户信息
   * @param userId 用户id
   * @param user 修改的用户信息
   * @return 修改后的用户信息
   */
  @RequestMapping("changeInformation")
  public JsonResult changeInformation(Integer userId, User user) {
    UserDTO data = userService.changeInformation(userId, user);
    //  前面没有出现异常则修改成功

    //  修改11.9
    JsonResult result = new JsonResult(OK);
    result.addData("userInfo", data);
    return result;
    //  11.9
  }

  /**
   * 设置标签
   * @param username 用户名
   * @param tag1 标签1
   * @param tag2 标签2
   * @param tag3 标签3
   * @return 新的用户信息
   */
  @RequestMapping("setTag")
  public JsonResult setTag(String username, String tag1, String tag2, String tag3) {
    UserDTO data = userService.setTags(username, tag1, tag2, tag3);

    //  返回修改标签后的用户信息
    JsonResult result = new JsonResult(OK);
    result.addData("userInfo", data);
    return result;
  }

  /**
   * 修改密码
   * @param username 用户名
   * @param password 密码
   * @return json
   */
  @RequestMapping("changePassword")
  public JsonResult changePassword(String username, String password) {
    userService.changePassword(username, password);
    return new JsonResult(OK);
  }

  /**
   * 设置钱包地址
   * @param username 用户名
   * @param pocket 钱包地址
   * @return json
   */
  @RequestMapping("setPocket")
  public JsonResult setPocket(String username, String pocket) {
    userService.setPocket(username, pocket);
    return new JsonResult(OK);
  }

  /**
   * 上传头像
   * @param id 用户id
   * @param multipartFile 头像文件
   * @return json
   */
  @RequestMapping("setAvatar")
  public JsonResult setAvatar(Integer id, MultipartFile multipartFile) {
    userService.setAvatar(id, multipartFile);
    return new JsonResult(OK);
  }

  /**
   * 获取头像
   * @param username 用户名
   * @param response http请求的response
   */
  @RequestMapping("getAvatar")
  public void getAvatar(String username, HttpServletResponse response) {
    userService.getAvatar(username, response);
  }

  /**
   * 根据userId获取用户信息
   * @param id 用户id
   * @return 用户信息
   */
  @RequestMapping("getUserById")
  public JsonResult getUserById(Integer id) {
    User user = userService.getUserById(id);
    JsonResult result = new JsonResult(OK);
    result.addData("userInfo",user);
    return result;
  }

  /**
   * 忘记密码
   * @param username 用户名
   * @param emailAddress 邮箱
   * @param captcha 验证码
   * @return json
   */
  @RequestMapping("forgetPassword")
  public JsonResult forgetPassword(String username,String emailAddress,String captcha) {
    User user = userService.getUserByUsername(username);
    if(user==null) {
      throw new UserNotExistException("用户不存在");
    }
    //  判断邮箱是否正确
    if(!user.getEmail().equals(emailAddress)) {
      throw new EmailException("请使用该账号绑定的邮箱");
    }
    //  判断验证码
    if (!Objects.equals(captchaList.get(user.getEmail()), captcha)) {
      throw new CaptchaException("验证码错误");
    }

    JsonResult result = new JsonResult(OK);
    result.addData("username",username);
    return result;
  }

  @RequestMapping("passwordCaptcha")
  public void passwordCaptcha(String username,String emailAddress) {
    User user = userService.getUserByUsername(username);
    if(user==null) {
      throw new UserNotExistException("用户不存在");
    }
    //  判断邮箱是否正确
    if(!user.getEmail().equals(emailAddress)) {
      throw new EmailException("请使用该账号绑定的邮箱");
    }

    String captcha = userService.sendCaptcha(emailAddress);
    //  hashmap会直接进行覆盖
    captchaList.put(emailAddress, captcha);
  }

  /**
   * 实名认证
   * @param front 身份证正面文件
   * @param negative 身份证背面文件
   * @param id 用户id
   * @return json
   */
  @RequestMapping("certify")
  public JsonResult certify(MultipartFile front,MultipartFile negative,Integer id) {
    userService.certify(front,negative,id);

    return new JsonResult(OK);
  }

  /**
   * 获取实名信息
   * @param username 用户名
   * @param type front or negative
   * @param response http的response
   */
  @RequestMapping("getCertification")
  public void getCertification(String username, String type, HttpServletResponse response) {
    userService.getCertification(username,type,response);
  }

}
